#ifndef NANE_BIND_H
#   define NANE_BIND_H

#   include "nane/core/function/ForwardParamT.h"

namespace nane
{
    template<typename F>
    class Bind1st
    {
    public:
        typedef typename F::TReturn TReturn;
        typedef typename F::TParam2 TParam1;
        typedef typename F::TParam3 TParam2;
        typedef typename F::TParam4 TParam3;
        typedef void TParam4;

        Bind1st(F _functor, typename F::TParam1 _param1 )
            : m_functor( _functor )
            , m_param1( _param1 )
        {

        }

        TReturn operator()()
        {
            return m_functor(m_param1);
        }

        TReturn operator()( typename ForwardParamT<typename F::TParam2>::Type _a2 )
        {
            return m_functor(m_param1, _a2);
        }

        TReturn operator()( typename ForwardParamT<typename F::TParam2>::Type _a2
                          , typename ForwardParamT<typename F::TParam3>::Type _a3 )
        {
            return m_functor(m_param1, _a2, _a3);
        }

        TReturn operator()( typename ForwardParamT<typename F::TParam2>::Type _a2
                          , typename ForwardParamT<typename F::TParam3>::Type _a3
                          , typename ForwardParamT<typename F::TParam4>::Type _a4 )
        {
            return m_functor(m_param1, _a2, _a3, _a4);
        }

    private:
        F m_functor;
        typename F::TParam1 m_param1;
    };

    template<typename F>
    Bind1st<F> bind1st( F _functor, typename F::TParam1 _param1 )
    {
        return Bind1st<F>(_functor, _param1);
    }
}   // namespace nane

#endif	// NANE_BIND_H
